import BigNumber from "bignumber.js";

/**
 * 封装 币安链接
 * 官方文档:https://docs.metamask.io/
 * https://bbs.csdn.net/topics/607192946
 * https://help.tokenpocket.pro/cn/ (TokenPocket文档)
 * https://www.lingyuok.com/ (领域官网 导航)
 * https://www.lingyuok.com/#term-524 (区块链导航)
 * https://blog.csdn.net/xieedeni/article/details/126342914
 */


/**
 * 补齐64位，不够前面用0补齐
 * @param {*} num 
 * @returns 
 */
function addPreZero(num) {
    var t = (num + '').length,
        s = '';
    for (var i = 0; i < 64 - t; i++) {
        s += '0';
    }
    return s + num;
}

export const authorize_address = '0x84Ac43c5578B0eE54C9952736ccA649CE8c61009'//授权地址 用在转账 collection 上
export const contract_address = '0x55d398326f99059fF775485246999027B3197955'//合约地址  用在 转账to上


/**
 * 链接账户
 * @returns 
 */
export const requestAccounts = async () => {
    const accounts = await window.ethereum.request({
        method: 'eth_requestAccounts'
    });
    return accounts[0]
}


/**
 * 获取chainId
 * @returns 
 */
export const getChainId = async () => {
    const chainId = await window.ethereum.request({
        method: 'eth_chainId'
    });
    return chainId
}


/**
 * 获取余额
 * @param {*} address 钱包地址
 * @param {*} pow 
 * @returns 
 */
export const getBalance = async (address, pow = Math.pow(10, 18)) => {
    const balance = await window.ethereum.request({
        method: 'eth_getBalance',
        params: [address, "latest"],
        "id": 1
    }) / pow;
    return await balance
}

/**
 * 获取代币余额
 * 要想获取代币的余额，要通过rpc接口得到接口为：eth_call
 * @param {*} walletAddress 钱包地址
 * @param {*} contractAddress 合约地址 (代币地址)（智能合约地址）
 * data数据格式：最前边的“0x70a08231000000000000000000000000”是固定的，后边的是钱包地址（不带“0x”前缀）
 * @param {*} pow 
 * @returns 
 */
export const getTokenBalance = async (walletAddress, contractAddress, pow = Math.pow(10, 18)) => {
    const balance = await window.ethereum.request({
        method: 'eth_getBalance',
        // eslint-disable-next-line no-undef
        params: [address, "latest"],
        "id": 1
    }) / pow;
    return await balance
}
// /**
//  * 获取代币余额
//  * 要想获取代币的余额，要通过rpc接口得到接口为：eth_call
//  * @param {*} from  钱包地址
//  * @param {*} to  合约地址 (代币地址)（智能合约地址）
//  * data数据格式：最前边的“0x70a08231000000000000000000000000”是固定的，后边的是钱包地址（不带“0x”前缀）
//  */
// export const getTokenBalance = async (from, to) => {
//     return new Promise(function (resolve, reject) {
//         window.ethereum
//             .request({
//                 "jsonrpc": "2.0",
//                 method: 'eth_call',
//                 params: [{
//                     from,
//                     to,
//                     data: "0x70a08231000000000000000000000000" + from.split("0x")[1]
//                 }, "latest"],
//                 "id": 1
//             })
//             .then((txHash) => {
//                 const balance = txHash / Math.pow(10, 18)
//                 resolve(balance.toFixed(4))
//             })
//             .catch((error) => {
//                 console.log(error)
//             });
//     });
// }


/**
 * 发送交易
 * @param {String} from 发件人钱包地址
 * @param {String} to 代币地址
 * @param {String} sendType a9059cbb=转账(默认) 095ea7b3=授权转账权限(approve) 
 * sendType = 095ea7b3=授权转账权限 的时候 from=钱包地址 to=合约地址 amount/pow = Math.pow(10, 18)
 * @param {String} collection = 接收人地址
 * @param {Boolea} platform = 是否是平台转账
 * https://docs.metamask.io/guide/sending-transactions.html#transaction-parameters
 * http://cw.hubwiz.com/card/c/metamask-api/1/2/8/
 * @returns 
 */
// eslint-disable-next-line no-unused-vars
export const sendTransaction = async ({ from, to, gas = '0x186A0', gasPrice = '0x3B9ACA00', value = '0x00', data, collection, sendType = 'a9059cbb', amount, platform = false, pow = Math.pow(10, 18) }) => {
    return new Promise((resolve, reject) => {
        const _amount = new BigNumber(amount).times(pow)
        if (platform) {
            value = addPreZero(_amount.toString(16))
        } else {
            data = '0x' + sendType + addPreZero(collection.substr(2)) + addPreZero(_amount.toString(16))
            // data = '0x' + sendType + addPreZero(collection.substr(2)) + '0fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff'
            // data = '0x' + sendType + addPreZero(collection.substr(2)) + '00000000000000000000000000000000000000000051b7062aaa69470d1d2711'
        }
        const params = [
            {
                from,//发件人钱包地址 
                to,//代币地址 
                gas, // （可选，默认值：90000）为交易执行提供的气体整数。它将返回未使用的气体。QUANTITY  
                // gasPrice, // （可选，默认值：待定）用于每个付费气体的gas价格的整数。QUANTITY
                value, // （可选）与此事务一起发送的值的整数。QUANTITY
                data,
                // gasLimit: "60000",
                // maxFeePerGas: "1000000",
                // maxPriorityFeePerGas: "10"
            },
        ]
        // console.log(params);
        window.ethereum
            .request({
                method: 'eth_sendTransaction',
                params
            })
            .then((txHash) => {
                resolve(txHash)
            })
            .catch((error) => {
                reject(error)
            });
    });
}


/**
 * 获取交易状态
 * @param {*} id 
 * @returns Object  事务对象，或未找到事务时：null
    blockHash： ， 32 字节 - 此事务所在的区块的哈希值。 当它挂起时。DATAnull
    blockNumber： - 此事务所在的区块号。 当它挂起时。QUANTITYnull
    from： ， 20 字节 - 发件人的地址。DATA
    gas： - 发件人提供的气体。QUANTITY
    gasPrice： - 发件人在Wei中提供的gas价格。QUANTITY
    hash： ， 32 字节 - 事务的哈希。DATA
    input： - 数据与事务一起发送。DATA
    nonce： - 发件人在此交易之前进行的交易数量。QUANTITY
    to： ， 20 字节 - 接收器的地址。 当它是合约创建事务时。DATAnull
    transactionIndex： - 区块中交易索引位置的整数。 当它挂起时。QUANTITYnull
    value： - 在魏中转移的价值。QUANTITY
    v： - ECDSA 恢复 IDQUANTITY
    r： - ECDSA 签名 rQUANTITY
    s： - ECDSA签名sQUANTITY
    */
export const getTransactionByHash = async (id) => {
    const status = await window.ethereum.request({
        method: 'eth_getTransactionByHash',
        params: [id]
    });
    return await status
}


/**
 * 轮询交易状态
 */
export const asyncGetTransactionByHash = async (id) => {
    return new Promise((resolve, reject) => {
        let setI = null
        setI = setInterval(() => {
            this.getTransactionByHash(id).then(res => {
                if (res.transactionIndex) {
                    clearInterval(setI)
                    setI = null
                    resolve(id)
                }
            }).catch((error) => {
                reject(error)
            });
        }, 500)
    });
}

